#ifndef TIMEHELPER_HPP
#define TIMEHELPER_HPP

#include <QDateTime>

// 时间单位枚举
enum class TimeEnum {
    Hours,
    Minutes,
    Seconds
};


/**
 * @brief 将值向上舍入到最近的倍数
 * @param value 原始值
 * @param multiple 倍数
 * @return 舍入后的值
 */
inline qint64 roundUpToNearest(qint64 value, qint64 multiple) {
    if (multiple == 0)
        return value;
    qint64 remainder = value % multiple;
    if (remainder == 0)
        return value;
    return value + multiple - remainder;
}

/**
 * @brief 计算两个 QDateTime 的时间差并舍入到最近的倍数
 * @param start 开始时间
 * @param end   结束时间
 * @param unit  需要返回的单位（小时 / 分钟 / 秒）
 * @param roundMultiple 舍入到的倍数，默认为10（仅适用于秒）
 * @return 差值(整数)
 */
inline qint64 calcTimeDiff(const QDateTime &start, const QDateTime &end, TimeEnum unit, qint64 roundMultiple = 10) {
    // secsTo: 计算 start 到 end 相差多少秒
    qint64 diffSeconds = start.secsTo(end);
    switch (unit) {
    case TimeEnum::Hours:
        return diffSeconds / 3600;  // 转成小时
    case TimeEnum::Minutes:
        return diffSeconds / 60;    // 转成分钟
    case TimeEnum::Seconds:
    default:
        return roundUpToNearest(diffSeconds, roundMultiple); // 舍入到最近的倍数
    }
}

/**
 * @brief 计算 (current - start)，并限定在 [0, (end - start)] 范围内
 * @param start  开始时间
 * @param end    结束时间
 * @param current 当前项的时间
 * @return 与 startTime 的相对秒数 (double)
 */
inline double convertToRelativeSeconds(const QDateTime &start, const QDateTime &end, const QDateTime &current) {
    qint64 startSec   = start.toSecsSinceEpoch();
    qint64 endSec     = end.toSecsSinceEpoch();
    qint64 currentSec = current.toSecsSinceEpoch();

    // 若当前时间早于 start，则返回 0
    if (currentSec <= startSec) {
        return 0.0;
    }
    // 若当前时间晚于 end，则返回 (endSec - startSec)
    if (currentSec >= endSec) {
        return (double)(endSec - startSec);
    }
    // 否则返回 [0, end - start] 之间
    return (double)(currentSec - startSec);
}


/**
 * @brief [startTime, endTime] 是否完全落在 [startRangeTime, endRangeTime] 区间内
 * @param startRangeTime  开始区间时间
 * @param endRangeTime    结束区间时间
 * @param startTime 当前开始时间
 * @param endTime 当前结束时间
 * @return bool
 */
inline bool isTimeWithinRange(const QDateTime& startRangeTime, const QDateTime& endRangeTime,
                              const QDateTime& startTime, const QDateTime& endTime) {
    // 验证 QDateTime 对象的有效性
    if (!startRangeTime.isValid()) {
        // qWarning() << "startRangeTime 无效";
        return false;
    }
    if (!endRangeTime.isValid()) {
        // qWarning() << "endRangeTime 无效";
        return false;
    }
    if (!startTime.isValid()) {
        // qWarning() << "startTime 无效";
        return false;
    }
    if (!endTime.isValid()) {
        // qWarning() << "endTime 无效";
        return false;
    }

    // 确保时间顺序正确
    if (startRangeTime > endRangeTime) {
        // qWarning() << "startRangeTime 晚于 endRangeTime";
        return false;
    }
    if (startTime > endTime) {
        // qWarning() << "startTime 晚于 endTime";
        return false;
    }

    // 判断给定的时间区间是否在范围时间内
    // 即 startRangeTime <= startTime <= endTime <= endRangeTime
    bool isWithin = (startTime >= startRangeTime) && (endTime <= endRangeTime);

    // 处理边界情况
    if (isWithin) {
        // qDebug() << "给定的时间区间在范围时间内";
    } else {
        // qDebug() << "给定的时间区间不在范围时间内";
    }

    return isWithin;
}

/**
 * @brief triggerTime 是否完全落在 [startRangeTime, endRangeTime] 区间内
 * @param startRangeTime  开始区间时间
 * @param endRangeTime    结束区间时间
 * @param triggerTime 当前触发时间
 * @return bool
 */
inline bool isTimeWithinRange(const QDateTime& startRangeTime, const QDateTime& endRangeTime,
                              const QDateTime& triggerTime) {
    // 验证 QDateTime 对象的有效性
    if (!startRangeTime.isValid() || !endRangeTime.isValid() || !triggerTime.isValid()) {
        return false;
    }

    // 确保时间顺序正确
    if (startRangeTime > endRangeTime) {
        return false;
    }

    // 判断给定的时间点是否在范围时间内
    return (triggerTime >= startRangeTime) && (triggerTime <= endRangeTime);
}


/**
 * @brief 计算 triggerTime 相对于 startTime 的时间偏移，单位为秒
 *
 * @param startTime 起始时间
 * @param triggerTime 触发时间
 * @return qint64 时间偏移量（秒）
 *
 *   QDateTime startTime = QDateTime::fromString("2024-01-01T00:00:00", Qt::ISODate);
 *   QDateTime triggerTime = QDateTime::fromString("2024-01-01T01:30:45", Qt::ISODate);
 *
 *   qint64 offsetSeconds = calculateTimeOffsetInSeconds(startTime, triggerTime);
 *   qDebug() << "时间偏移量（秒）：" << offsetSeconds; // 输出：5445
 */
inline double calculateTimeOffsetInSeconds(const QDateTime& startTime, const QDateTime& triggerTime) {
    // 确保两个时间都是在相同的时区（转换为 UTC）
    QDateTime normalizedStart = startTime.toUTC();
    QDateTime normalizedTrigger = triggerTime.toUTC();

    // 获取自 Unix 纪元以来的毫秒数
    qint64 startMillis = normalizedStart.toMSecsSinceEpoch();
    qint64 triggerMillis = normalizedTrigger.toMSecsSinceEpoch();

    // 计算毫秒差
    qint64 deltaMillis = triggerMillis - startMillis;

    // 转换为秒（保留两位小数）
    double deltaSeconds = deltaMillis / 1000.0;
    // 四舍五入到两位小数
    deltaSeconds = std::round(deltaSeconds * 100.0) / 100.0;

    return deltaSeconds;
}


#endif // TIMEHELPER_HPP
